<?php
namespace Framework\Library\Core;

use Framework\Library\Utility\PagingParameter;
use Framework\Library\Utility\IdentitySearcher;
/**
 * 数据集列表类
 */
abstract class Datalist{
	
	protected $identitySearcher;
	
	public $entitys = array();
	
	public $displayFields = array();
	protected $achtmlCallbacks = array();
	
	public $headerLinks = array();
	public $operationLinks = array();
	public $navigationLinks = array();
	
	public $recordCount;
	
	function __construct( $entity, $display_fields = NULL, $operations=NULL, $achtml_callbacks=NULL, $paging_parameter=NULL,$condition=NULL,$range=10){
		
		if (!empty($display_fields))$this->displayFields = $display_fields;
		if (!empty($achtml_callbacks)) $this->achtmlCallbacks = $achtml_callbacks;
		
		// 初始化分页器
		require_once __DIR__.'/../Utility/PagingParameter.class.php';
		if (empty($paging_parameter)) $paging_parameter = new PagingParameter();
		$paging_parameter->init($entity->module->application->request);
		
		// 初始化标识检索器
		require_once __DIR__.'/../Utility/IdentitySearcher.class.php';
		$this->identitySearcher = new IdentitySearcher($entity, $paging_parameter,$condition);
		$this->recordCount = $this ->identitySearcher ->getRecordCount();
		
		// 初始化列表的实体对象集合
		$this ->initEntitys();
		
		// 初始化列表的各种链接
		$this ->initHeaderLinks( $display_fields );
		$this ->initOperationLinks( $operations );
		$this ->initNavigationLinks();
		
	}
	
	private function initEntitys(){
		
		//取得当前列表的数据标识
		$ids = $this ->identitySearcher ->get();
		if ( empty($ids) ) return NULL;
		
		if ( !is_array($ids) ) throw new \Exception('标识搜索器返回了未知类型');
		
		$this->entitys = array();
		
		foreach ($ids as $id){
			
			array_push( $this->entitys, $this ->identitySearcher->entity->newInstance($id) );
			
		}
		
	}

	private function getOrderUrl( $order_field, $order_pattern ){
		
		$module = $this->identitySearcher->entity->module;
		$pagingParameter = $this->identitySearcher->pagingParameter;
		$request = $module->application->request;
		
		$params = array();
		$params[$pagingParameter->orderFieldIndex] = $order_field;
		$params[$pagingParameter->orderPatternIndex] = $order_pattern;
		$params[$pagingParameter->pageSizeIndex] = $pagingParameter->pageSize;
		$params[$pagingParameter->pagePositionIndex] = $pagingParameter->pagePosition;
		
		return $module->url($request->module,$request->action,$params);
		
	}

	private function getPageUrl( $page_number, $page_size = NULL ){
		
		$module = $this->identitySearcher->entity->module;
		$pagingParameter = $this->identitySearcher->pagingParameter;
		$request = $module->application->request;
		
		$params = array();
		$params[$pagingParameter->orderFieldIndex] = $pagingParameter->orderField;
		$params[$pagingParameter->orderPatternIndex] = $pagingParameter->orderPattern;
		
		if (empty($page_size)) $params[$pagingParameter->pageSizeIndex] = $pagingParameter->pageSize;
		else  $params[$pagingParameter->pageSizeIndex] = $page_size;
		
		if (empty($page_number)) $params[$pagingParameter->pagePositionIndex] = $pagingParameter->pagePosition;
		else  $params[$pagingParameter->pagePositionIndex] = $page_number;
		
		return $module->url($request->module,$request->action,$params);
		
	}
	
	private function initHeaderLinks( $fields ){
		
		$this ->headerLinks = array();
		
		foreach ( $fields as $field=>$name ){
			
			$this ->headerLinks[$field] = array(
					'name' =>$name,
					'asc_url' =>$this ->getOrderUrl( $field, 'asc' ),
					'desc_url' =>$this ->getOrderUrl($field, 'desc' )
					);
			
		}
		
	}
	
	private function initNavigationLinks( $range = 10 ){
		
		$pagingParameter = $this->identitySearcher->pagingParameter;
		
		$record_count = $this->recordCount;
		$page_count = ceil($record_count / $pagingParameter ->pageSize);
		
		$this ->navigationLinks = array();
		$this ->navigationLinks['first'] = $this ->getPageUrl(1);
		$this ->navigationLinks['last'] = $this ->getPageUrl($page_count);
		
		$range_start = $pagingParameter ->pagePosition - ($range/2);
		if ( $range_start < 1 ) $range_start = 1;
		
		for ( $i = $range_start; $i <= $page_count; $i++ ){
			$this ->navigationLinks['range'][$i] = $this ->getPageUrl($i);
		}
		
	}
	
	private function initOperationLinks( $operations ){
		
		$module = $this->identitySearcher->entity->module;
		
		$this ->operationLinks = array();
		
		foreach ( $this ->entitys as $entity ){
			
			$links = array();
			
			foreach ( $operations as $operation ){
				
				$params = array();
				
				if (!empty($operation['params'])){
					foreach ($operation['params'] as $p) {
						
						$rest = substr($p, 0, 1);
						if ($rest == '#') $p = $entity->data[substr($p,1)];
						
						array_push($params, $p);
						
					}
				}
				
				$link = array(
						'name' =>$operation['name'],
						'url' =>$module->url($operation['module'],$operation['action'],$params),
						'target'=>$operation['target']
				);
				
				array_push($links, $link);
																							
			}
			
			array_push($this ->operationLinks, $links);
			
		}
		
	}
	
	public function getHTML(){
		
		$HTML = '<table border="1">';
		
		$HTML .= "<tr>";
		
		foreach ($this->displayFields as $field=>$name){
			
			$HTML .= "<td>$name";
			$HTML .= '<a href="'.$this->headerLinks[$field]['asc_url'].'">升序</a>';
			$HTML .= '<a href="'.$this->headerLinks[$field]['desc_url'].'">倒序</a>';
			$HTML .= "</td>";
			
		}
		
		if (!empty($this->operationLinks)) $HTML .= "<td>操作</td>";
		
		$HTML .= "</tr>";
		
		foreach( $this->entitys as $key=>$entity){
			
			$HTML .= "<tr>";
			
			foreach ($this->displayFields as $field=>$name){
				
				if (!empty($this->achtmlCallbacks[$field])){
					$method = $this->achtmlCallbacks[$field];
					$displayString = $this->$method($entity->data[$field]);
				}else{
					$displayString = $entity->data[$field];
				}
				
				$HTML .= "<td>";
				$HTML .= $displayString;
				$HTML .= "</td>";
				
			}
			
			if (!empty($this->operationLinks[$key])) {
					
				$HTML .= '<td>';
					
				foreach ($this->operationLinks[$key] as $link){
			
					$HTML .= '<a href="'.$link['url'].'" target="'.$link['target'].'">'.$link['name'].'</a>';
			
				}
					
				$HTML .= '</td>';
					
			}
			
			$HTML .= "</tr>";
			
		}
		
		$HTML .= "</table>";
		
		$HTML .= '<p><a href="'.$this->navigationLinks['first'].'">首页</a>';
		
		foreach ($this->navigationLinks['range'] as $page_num=>$url){
			
			$HTML .= '<a href="'.$url.'">'.$page_num.'</a>';
			
		}
		
		$HTML .= '<a href="'.$this->navigationLinks['last'].'">尾页</a></p>';
		
		return $HTML;
		
	}
	
}